package cn.ctodb.mall.goods.service.impl;

import cn.ctodb.mall.goods.service.CategoryService;
import cn.ctodb.mall.goods.domain.Category;
import cn.ctodb.mall.goods.repository.CategoryRepository;
import cn.ctodb.mall.goods.repository.search.CategorySearchRepository;
import cn.ctodb.mall.goods.service.dto.CategoryDTO;
import cn.ctodb.mall.goods.service.mapper.CategoryMapper;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;

import java.util.*;

import static org.elasticsearch.index.query.QueryBuilders.*;

/**
 * Service Implementation for managing Category.
 */
@Service
@Transactional
public class CategoryServiceImpl implements CategoryService {

    private final Logger log = LoggerFactory.getLogger(CategoryServiceImpl.class);

    private final CategoryRepository categoryRepository;

    private final CategoryMapper categoryMapper;

    private final CategorySearchRepository categorySearchRepository;

    public CategoryServiceImpl(CategoryRepository categoryRepository, CategoryMapper categoryMapper, CategorySearchRepository categorySearchRepository) {
        this.categoryRepository = categoryRepository;
        this.categoryMapper = categoryMapper;
        this.categorySearchRepository = categorySearchRepository;
    }

    /**
     * Save a category.
     *
     * @param categoryDTO the entity to save
     * @return the persisted entity
     */
    @Override
    public CategoryDTO save(CategoryDTO categoryDTO) {
        log.debug("Request to save Category : {}", categoryDTO);
        Category category = categoryMapper.categoryDTOToCategory(categoryDTO);
        category = categoryRepository.save(category);
        CategoryDTO result = categoryMapper.categoryToCategoryDTO(category);
        categorySearchRepository.save(category);
        return result;
    }

    /**
     * Get all the categories.
     *
     * @param pageable the pagination information
     * @return the list of entities
     */
    @Override
    @Transactional(readOnly = true)
    public Page<CategoryDTO> findAll(Pageable pageable) {
        log.debug("Request to get all Categories");
        Page<Category> result = categoryRepository.findAll(pageable);
        return result.map(category -> categoryMapper.categoryToCategoryDTO(category));
    }

    /**
     * Get one category by id.
     *
     * @param id the id of the entity
     * @return the entity
     */
    @Override
    @Transactional(readOnly = true)
    public CategoryDTO findOne(Long id) {
        log.debug("Request to get Category : {}", id);
        Category category = categoryRepository.findOne(id);
        CategoryDTO categoryDTO = categoryMapper.categoryToCategoryDTO(category);
        return categoryDTO;
    }

    /**
     * Delete the  category by id.
     *
     * @param id the id of the entity
     */
    @Override
    public void delete(Long id) {
        log.debug("Request to delete Category : {}", id);
        categoryRepository.delete(id);
        categorySearchRepository.delete(id);
    }

    /**
     * Search for the category corresponding to the query.
     *
     * @param query    the query of the search
     * @param pageable the pagination information
     * @return the list of entities
     */
    @Override
    @Transactional(readOnly = true)
    public Page<CategoryDTO> search(String query, Pageable pageable) {
        log.debug("Request to search for a page of Categories for query {}", query);
        Page<Category> result = categorySearchRepository.search(queryStringQuery(query), pageable);
        return result.map(category -> categoryMapper.categoryToCategoryDTO(category));
    }

    @Override
    public List<Map<String, Object>> getNavbar() {
        try {
            Category root = categoryRepository.findOne(1L);
            if (root == null) return null;
            return (List<Map<String, Object>>) getDto(root).get("children");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Map<String, Object> getDto(Category channel) throws JSONException {
        Map<String, Object> map = new HashMap<>();
        map.put("id", channel.getId());
        map.put("name", channel.getCatName());
        map.put("iconUrl", channel.getIcon01());
        List<Map<String, Object>> list = new ArrayList<>();
        Set<Category> set = channel.getChildren();
        if (set.size() > 0) {
            for (Category channel2 : set) {
                list.add(getDto(channel2));
            }
            map.put("children", list);
        }
        return map;
    }

}
